package com.winit.uCloud.manager;

import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.winit.common.util.ConfigUtil;
import com.winit.common.util.FileUtil;
import com.winit.deploy.bean.DeployEnum;
import com.winit.deploy.service.DeployService;
import com.winit.project.core.bean.PackageTypeEnum;
import com.winit.project.core.branch.Project;
import com.winit.project.core.edition.PackageEdition;
import com.winit.project.service.ProjectService;
import com.winit.project.util.ProjectUtil;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import org.springframework.util.StringUtils;

import java.io.File;
import java.util.ArrayList;
import java.util.List;

/**
 * Created by wangjian on 16/11/14.
 */
@Component
public class UCVersionManager {

    private static Logger logger = LoggerFactory.getLogger(UCVersionManager.class);

    @Autowired
    private DeployService deployService;
    @Autowired
    private ProjectService projectService;

    public List<JSONObject> getProjectVersions(String apps) {
        List<JSONObject> list = new ArrayList<>();
        String[] app = apps.split(",");
        for (String trunkName : app) {
            JSONObject object = null;
            if ("erp".equals(trunkName)) {
                object = getErpOrOwmsVersion("tms");
                object.put("app", trunkName);
                list.add(object);
                continue;
            } else if ("owms".equals(trunkName)) {
                object = getErpOrOwmsVersion("owms");
                object.put("app", trunkName);
                list.add(object);
                continue;
            }

            //线上环境版本
            object = getProjectVersion(trunkName, DeployEnum.ONLINE);
            if (object != null) {
                list.add(getRtnObject(object.getString("projectName"), object.getString("editionNum"), "product"));
                continue;
            }
            //nas下线上版本路径
            object = getNasLatestVersion(trunkName);
            if (object != null) {
                list.add(object);
                continue;
            }

            //测试通过版本
            object = getProjectVersion(trunkName, DeployEnum.TESTPASS);
            if (object != null) {
                list.add(getRtnObject(object.getString("projectName"), object.getString("editionNum"), "qaTest"));
                continue;
            }

            object = new JSONObject();
            object.put("package_path", "");
            object.put("version", "");
            object.put("version_type", "none");
            object.put("app", trunkName);
            list.add(object);
        }
        return list;
    }

    public List<JSONObject> getProjectOnlineVersions(String apps, String type) {
        List<JSONObject> list = new ArrayList<>();
        JSONArray jsonArray = JSONArray.parseArray(apps);
        for (int i = 0; i < jsonArray.size(); i++) {
            String name = jsonArray.getString(i);
            if ("product".equals(type)) {
                JSONObject object = getProjectVersion(name, DeployEnum.ONLINE);
                if (object != null) {
                    JSONObject json = getRtnObject(object.getString("projectName"), object.getString("editionNum"), "product");
                    json.put("projectName", object.getString("projectName"));
                    json.put("editionNum", object.getString("editionNum"));
                    list.add(json);
                }
            } else if ("plan".equals(type)) {
                try {
                    Project project = new Project(name, true);
                    List<PackageEdition> l = project.listEditions(true, true);
                    if (l.size() > 0) {
                        String editionNum = l.get(0).getEditionNum();
                        if(l.size() > 1){
                            editionNum = l.get(1).getEditionNum();
                        }
                        JSONObject json = getRtnObject(name, editionNum, "plan");
                        json.put("projectName", name);
                        json.put("editionNum", editionNum);
                        list.add(json);
                    }
                } catch (Exception e) {
                    logger.error("com.winit.uCloud.manager.UCVersionManager.getProjectOnlineVersions 异常.", e);
                }
            }

        }
        return list;
    }

    private JSONObject getProjectVersion(String trunkName, DeployEnum deployEnum) {
        String version = deployService.getOnlineOrStagingVersion(trunkName, deployEnum, "");
        JSONObject object = new JSONObject();
        if (!StringUtils.isEmpty(version)) {
            String projectName = version.split("#")[0];
            String editionNum = version.split("#")[1];
            try {
                if (projectService.isEditionExist(projectName, editionNum)) {
                    object.put("projectName", projectName);
                    object.put("editionNum", editionNum);
                    logger.info("com.winit.uCloud.manager.UCVersionManager.getProjectVersion object:" + object);
                    return object;
                }
            } catch (Exception e) {
                logger.error("com.winit.uCloud.manager.UCVersionManager.getProjectVersion 异常", e);
            }
        }
        logger.info("com.winit.uCloud.manager.UCVersionManager.getProjectVersion obj=null name:" + trunkName);
        return null;
    }

    /**
     * 存在工程版本时,拼接返回数据
     *
     * @param projectName
     * @param editionNum
     * @param versionType
     * @return
     */
    private JSONObject getRtnObject(String projectName, String editionNum, String versionType) {
        JSONObject object = new JSONObject();
        object.put("version_type", versionType);
        object.put("app", ProjectUtil.getTrunkProjectName(projectName));
        try {
            Project project = new Project(projectName, true);
            String editionPath = ProjectUtil.getEditionPath(projectName, editionNum);
            StringBuffer packagePath = new StringBuffer();
            packagePath.append(editionPath).append("target/");
            PackageTypeEnum typeEnum = Enum.valueOf(PackageTypeEnum.class, project.getProjectSetConfig().getPackageType().toUpperCase());
            switch (typeEnum) {
                case MAVEN_WAR:
                    packagePath.append(ProjectUtil.getEditionNasNum(editionPath)).append("/").append(project.getProjectSetConfig().getWarName()).append(".war");
                    break;
                case PHP:
                    packagePath.append(project.getProjectSetConfig().getPackageName()).append(".zip");
                    break;
                default:
                    break;
            }
            object.put("package_path", packagePath.toString());
            object.put("version", projectName + "@" + editionNum);
        } catch (Exception e) {
            object.put("package_path", "");
            object.put("version", "");
            object.put("version_type", "none");
            logger.error("com.winit.uCloud.manager.UCVersionManager.getRtnObject 异常", e);
        }
        logger.info("com.winit.uCloud.manager.UCVersionManager.getRtnObject object=" + object);
        return object;
    }

    private JSONObject getNasLatestVersion(String trunkName) {
        JSONObject object = new JSONObject();
        String nas_dir = ConfigUtil.getValue("nas_latest_product");
        StringBuffer path = new StringBuffer();
        path.append(StringUtils.isEmpty(nas_dir) ? "/mnt/build/latest.product" : nas_dir)
                .append("/").append(ProjectUtil.getTrunkProjectName(trunkName));
        File file = new File(path.toString());
        if (!file.exists() || file.listFiles().length == 0) {
            logger.info("com.winit.uCloud.manager.UCVersionManager.getNasLatestVersion 目录不存在。path=" + path.toString());
            return null;
        }

        String package_path = "";
        String version = "";

        for (File f : file.listFiles()) {
            if (f.getName().endsWith(".war")
                    || f.getName().endsWith(".zip")) {
                package_path = f.getAbsolutePath();
            }
            if (f.getName().endsWith(".version")) {
                version = f.getName().replace(".version", "");
            }
        }

        if (StringUtils.isEmpty(package_path)) {
            logger.info("com.winit.uCloud.manager.UCVersionManager.getNasLatestVersion 找不到发布包。path=" + path.toString());
            return null;
        }

        object.put("package_path", package_path.replace("Winit_release", "winitRelease"));
        object.put("version", version);
        object.put("version_type", "product");
        object.put("app", ProjectUtil.getTrunkProjectName(trunkName));
        logger.info("com.winit.uCloud.manager.UCVersionManager.getNasLatestVersion object=" + object);
        return object;
    }

    private JSONObject getErpOrOwmsVersion(String type) {
        JSONObject object = new JSONObject();
        StringBuffer path = new StringBuffer();
        path.append("/mnt/winitRelease/").append(type);
        File file = new File(path.toString());
        if (!file.exists()) {
            logger.info("com.winit.uCloud.manager.UCVersionManager.getErpOrOwmsVersion 目录不存在。path=" + path.toString());
            object.put("package_path", "");
            object.put("version", "");
            object.put("version_type", "none");
            return object;
        }
        List<File> list = new ArrayList<>();
        for (File f : file.listFiles()) {
            list.add(f);
        }
        list = FileUtil.sortFileDESC(list);
        if (list.size() == 0) {
            logger.info("com.winit.uCloud.manager.UCVersionManager.getErpOrOwmsVersion 目录下没有文件。path=" + path.toString());
            object.put("package_path", "");
            object.put("version", "");
            object.put("version_type", "none");
            return object;
        }
        File f = list.get(0);
        object.put("package_path", f.getAbsolutePath());
        object.put("version", f.getName());
        object.put("version_type", "product");
        logger.info("com.winit.uCloud.manager.UCVersionManager.getErpOrOwmsVersion。object=" + object);
        return object;
    }

}
